import json
import uuid
import string
from faker import Faker
import random
from datetime import datetime, timedelta

# 初始化Faker，支持多语言
fake_zh = Faker("zh_CN")
fake_en = Faker("en_US")
Faker.seed(42)  # 固定种子，保证结果可复现

# 颜色与ID的映射关系
COLOR_MAP = {
    None: ("", ""),
    "red": ("#FF0000", "ff0000"),
    "blue": ("#0000FF", "0000ff"),
    "green": ("#00FF00", "00ff00"),
    "yellow": ("#FFFF00", "ffff00"),
    "white": ("#FFFFFF", "ffffff"),
    "black": ("#000000", "000000")
}

def generate_random_image_url():
    """生成随机图片URL，模仿示例格式"""
    base_url = "https://s1-imfile.feishucdn.com/static-resource/v1/"
    uuid_part = str(uuid.uuid4()).replace("-", "")[:30]  # 生成UUID并缩短
    random_chars = ''.join(random.choices(string.ascii_lowercase + string.digits, k=5))
    return f"{base_url}{uuid_part}{random_chars}-?image_size=noop&cut_type=&quality=&format=png&sticker_format=.webp"

def generate_random_avatar_data():
    """生成随机头像数据字典，确保color和color_id对应"""
    # 随机选择颜色
    color_choice = random.choice([None, "red", "blue", "green", "yellow", "white", "black"])
    
    # 获取对应的颜色值和ID
    color_value, color_id = COLOR_MAP[color_choice]
    
    return {
        "color": color_value if color_choice else None,  # None时保持None
        "color_id": color_id,
        "content": None,
        "image": {
            "large": generate_random_image_url()
        },
        "source": random.choice(["image", "gravatar", "custom"])  # 随机来源
    }

def generate_biz_id(prefix="BIZ"):
    """
    生成类似示例的业务ID
    
    参数:
    prefix (str): ID前缀，默认为"BIZ"
    
    返回:
    str: 格式为"{prefix}_{uuid}"的ID
    """
    # 生成UUID并转换为小写字符串
    uuid_str = str(uuid.uuid4()).lower()
    
    # 随机替换1-2个字符为小写字母（模拟示例中的"l"）
    if random.random() > 0.3:  # 70%的概率添加字母替换
        uuid_list = list(uuid_str)
        # 随机选择1-2个位置替换为字母
        for _ in range(random.randint(1, 2)):
            pos = random.randint(0, len(uuid_list) - 1)
            # 只替换数字部分（避免替换连字符）
            if uuid_list[pos].isdigit():
                uuid_list[pos] = random.choice('abcdefghijklmnopqrstuvwxyz')
        uuid_str = ''.join(uuid_list)
    
    # 移除UUID中的连字符
    uuid_str = uuid_str.replace('-', '')
    
    return f"{prefix}_{uuid_str}"

def generate_attachment(n : int) -> list:
    res = []

    for i in range(n):
        d = {
            "id" : "BIZ_b38406e0f3a048c2a245ffeb9a14e42a"
        }
        res.append(d)
    
    return res

def generate_region_data(level : int):
    """生成随机的区域信息数据"""
    
    # 生成中英文全路径
    chinese_path = generate_chinese_full_path(level)
    
    return {
        "isDeleted": random.choice([False, False, False, True]),  # 75%概率False
        "fullPath": [
            {
                "language_code": 2052,  # 简体中文
                "text": chinese_path
            }
        ],
        "level": level
    }

def generate_chinese_full_path(level):
    """生成中文全路径"""
    levels = []
    
    # 根据层级生成路径
    if level >= 1:
        levels.append(fake_zh.province())  # 省级
    if level >= 2:
        levels.append(fake_zh.city())  # 市级
    if level >= 3:
        levels.append(fake_zh.district())  # 区/县级
    if level >= 4:
        levels.append(fake_zh.street_name())  # 街道级
    if level >= 5:
        levels.append(fake_zh.street_suffix() + "小区")  # 小区级
    
    return "/".join(levels)


def generate_phone():
    """生成符合要求的手机号码（包含dialing_code、country_code、number三个字段）{insert\_element\_0\_}"""
    return {
        "dialing_code": "+86",
        "country_code": "CN",
        "number": fake_zh.phone_number()[:11],  # 确保11位数字
    }


def generate_decimal():
    """生成符合规则的定点数（整数≤18位，小数≤9位）{insert\_element\_1\_}"""
    # 限制整数部分为更小的范围，避免科学计数法
    int_part = str(random.randint(0, 10**15 - 1))  # 减少到15位避免科学计数法
    decimal_digits = random.randint(1, 9)  # 小数位数1-9位
    decimal_part = str(random.randint(1, 10**decimal_digits - 1)).zfill(decimal_digits)
    return f"{int_part}.{decimal_part}" if decimal_part else int_part


def generate_number():
    """生成符合要求的浮点数（整数≤15位，小数≤9位，避免科学计数法）{insert\_element\_2\_}"""
    # 生成较小范围的整数部分，避免科学计数法
    int_part = random.randint(1, 10**15 - 1)  # 限制为12位整数
    decimal_digits = random.randint(1, 9)  # 小数位数1-6位
    decimal_part = random.randint(1, 10**decimal_digits - 1)
    
    # 手动构造数字字符串，确保不会变成科学计数法
    number_str = f"{int_part}.{str(decimal_part).zfill(decimal_digits)}"
    return float(number_str)

def generate_number(n_integer : int, n_decimal : int):
    """生成符合要求的浮点数（整数≤18位，小数≤9位）{insert\_element\_2\_}"""
    return float(f"{random.randint(0, 10**n_integer - 1)}.{random.randint(0, 10**n_decimal - 1)}")


def generate_datetime():
    """生成合法的日期时间（Unix时间戳或指定格式字符串）
    标签：zh_CN="日期时间"，en_US="DateTime"
    支持格式：
    - 字符串：YYYY-MM-DD HH:MM:SS（如"2025-03-31 08:00:00"）
    - 带时区字符串：YYYY-MM-DD HH:MM:SS+XX（如"2025-03-31 08:00:00+08"）
    - 时间戳：整数或字符串形式（如1750927056368或"1750927056368"）
    """
    format_choice = random.randint(0, 3)  # 0: timestamp int, 1: timestamp str, 2: datetime str, 3: datetime str with tz
    
    if format_choice == 0:
        # 生成2020-2030年的时间戳（整数格式）
        start_ts = int(datetime(2020, 1, 1).timestamp() * 1000)  # 毫秒级时间戳
        end_ts = int(datetime(2030, 1, 1).timestamp() * 1000)
        return random.randint(start_ts, end_ts)
    elif format_choice == 1:
        # 生成2020-2030年的时间戳（字符串格式）
        start_ts = int(datetime(2020, 1, 1).timestamp() * 1000)
        end_ts = int(datetime(2030, 1, 1).timestamp() * 1000)
        return str(random.randint(start_ts, end_ts))
    elif format_choice == 2:
        # 生成"YYYY-MM-DD HH:MM:SS"格式
        dt = fake_zh.date_time_between(start_date="-10y", end_date="+10y")
        return dt.strftime("%Y-%m-%d %H:%M:%S")
    else:
        # 生成"YYYY-MM-DD HH:MM:SS+XX"格式
        dt = fake_zh.date_time_between(start_date="-10y", end_date="+10y")
        timezone = random.choice(["+08", "+09", "+00", "-05", "+10"])
        return dt.strftime("%Y-%m-%d %H:%M:%S") + timezone


def generate_date():
    """生成合法的日期字符串（YYYY-MM-DD）{insert\_element\_4\_}"""
    return fake_zh.date()


def generate_text(max_len):
    """生成指定长度内的文本（符合maxLength约束）{insert\_element\_5\_}"""
    return fake_zh.text(max_nb_chars=max_len).strip()


def generate_email():
    """生成合法的邮箱格式{insert\_element\_6\_}"""
    return fake_zh.email()


def generate_option():
    """生成合法的选项值（匹配optionList中的apiName）{insert\_element\_7\_}"""
    return random.choice(["option_52d86948bb9", "option_2d86948bb9d"])


def generate_multilingual():
    """生成多语文本（zh_cn和en_us字段，总长度≤1000）{insert\_element\_8\_}"""
    return {
        "zh_cn": generate_text(500),
        "en_us": fake_en.text(max_nb_chars=500).strip(),
    }


def generate_rich_text():
    """生成富文本（支持单语言或多语言）{insert\_element\_9\_}"""
    return {
        "zh_CN": generate_text(500),
        "en_US": fake_en.text(max_nb_chars=500).strip(),
    }




def generate_bigint(n : int):
    """生成n位以内的整数{insert\_element\_10\_}"""
    return random.randint(-(10**n - 1), 10**n - 1)


def generate_record():
    """生成完整的record数据结构"""
    return {
        "record": {
            "phone_73c280f2783": generate_phone(),
            "decimal_a446e77c109": generate_decimal(),
            "number_a33398bfae5": generate_number(),
            "datetime_bfae52d8694": generate_datetime(),
            "richText_76d22d35024": generate_rich_text(),
            "multilingual_24673c280f2": generate_multilingual(),
            "date_398bfae52d8": generate_date(),
            "option_e52d86948bb": generate_option(),
            "text_7ea7d6a3339": generate_text(90),  # 长度≤100{insert\_element\_11\_}
            "bigint_7d6a33398bf": generate_bigint(),
            "boolean_e206a267520": random.choice(
                [True, False]
            ),  # 仅true/false{insert\_element\_12\_}
            "email_f2783b49d9a": generate_email(),
        }
    }

def load_invalid_values_from_json():
    """从rag_invalidCollection.json加载异常值"""
    try:
        with open("data/rag_invalidCollection.json", 'r', encoding='utf-8') as f:
            return json.load(f)
    except (FileNotFoundError, json.JSONDecodeError):
        return {}

def get_invalid_value(field_name, fallback_cases):
    """从JSON中获取异常值，如果没有则使用fallback_cases"""
    invalid_collection = load_invalid_values_from_json()
    
    if field_name in invalid_collection and invalid_collection[field_name]:
        # 从JSON中随机选择一个异常值
        return random.choice(invalid_collection[field_name])
    else:
        # 使用预设的fallback_cases
        return random.choice(fallback_cases)

def generate_phone_invalid():
    """生成不合法的手机号码对象（缺字段/号码位数不对/异常字符）"""
    fallback_cases = [
        {},  # 缺所有字段
        {"number": "12345"},  # 号码位数不对
        {"dialing_code": "+86", "country_code": "CN"},  # 缺number
        {"dialing_code": "86", "country_code": "CN", "number": "abcdefghijk"},  # 非数字
        {"dialing_code": "+86", "country_code": "CN", "number": "138000000000"},  # 超11位
    ]
    return get_invalid_value("phone_73c280f2783", fallback_cases)

def generate_decimal_invalid():
    """生成不合法的定点数（整数>18位/小数>9位/非数字）"""
    fallback_cases = [
        "1234567890123456789.1",  # 整数19位
        "123.1234567899",         # 小数10位
        "abc.def",                # 非数字
        "",                       # 空字符串
    ]
    return get_invalid_value("decimal_a446e77c109", fallback_cases)

def generate_number_invalid():
    """生成不合法的浮点数（整数>15位/小数>9位/字符串/None）"""
    fallback_cases = [
        9999999999999999999.0,  # 整数部分19位
        "not_a_number"     # 字符串
    ]
    return get_invalid_value("number_a33398bfae5", fallback_cases)

def generate_datetime_invalid():
    """生成不合法的日期时间（格式错误/非法日期/缺少秒/字符串）"""
    fallback_cases = [
        "2025/03/31 08:00:00",  # 错误分隔符
        "2025-02-30 08:00:00",  # 非法日期
        "2025-03-31 09:00",     # 缺少秒
        "2025-03-31-08:00:00+08", # 错误格式
        "abc",                  # 字符串
    ]
    return get_invalid_value("datetime_bfae52d8694", fallback_cases)

def generate_date_invalid():
    """生成不合法的日期字符串（格式错误/非法日期/空）"""
    fallback_cases = [
        "2025/03/31",      # 错误分隔符
        "2025-02-30",      # 非法日期
        "",                # 空
        "2025-13-01",      # 非法月份
    ]
    return get_invalid_value("date_398bfae52d8", fallback_cases)

def generate_text_invalid():
    """生成超长文本或空文本"""
    fallback_cases = [
        fake_zh.text(max_nb_chars=200),  # 超长
        None                              # None
    ]
    return get_invalid_value("text_7ea7d6a3339", fallback_cases)

def generate_email_invalid():
    """生成不合法邮箱（缺@/缺域名/非法字符）"""
    fallback_cases = [
        "test@",              # 缺域名
        "test.domain.com",    # 缺@符号
        "test.@domain.com",   # @前有无效点号
        "",                    # 空
    ]
    return get_invalid_value("email_f2783b49d9a", fallback_cases)

def generate_option_invalid():
    """生成不合法选项值（非optionList中的apiName）"""
    fallback_cases = [
        "aaa",   # 非法
        ""
    ]
    return get_invalid_value("option_e52d86948bb", fallback_cases)

def generate_multilingual_invalid():
    """生成不合法多语文本（超长/缺字段/非对象/空）"""
    fallback_cases = [
        {"zh_cn": "a" * 1200},  # 超长
        {"en_us": "b" * 1200},  # 超长
        "just a string"      # 非对象
    ]
    return get_invalid_value("multilingual_24673c280f2", fallback_cases)

def generate_rich_text_invalid():
    """生成不合法富文本（非对象/超长/空）"""
    fallback_cases = [
        "直接字符串",  # 非对象
        {"zh_CN": "a" * 1200}  # 超长
    ]
    return get_invalid_value("richText_76d22d35024", fallback_cases)

def generate_bigint_invalid():
    """生成不合法整数（超15位/非数字/空）"""
    fallback_cases = [
        str(10**19),  # 19位
        "abc123",    # 非数字
        ""          # 空
    ]
    return get_invalid_value("bigint_7d6a33398bf", fallback_cases)

def generate_boolean_invalid():
    """生成不合法布尔值（字符串/数字/空）"""
    fallback_cases = [
        "真",   # 字符串
        ""   # 空
    ]
    return get_invalid_value("boolean_e206a267520", fallback_cases)

def generate_record_invalid():
    """生成一组包含所有字段反例的record数据结构"""
    return {
        "record": {
            "phone_73c280f2783": generate_phone_invalid(),
            "decimal_a446e77c109": generate_decimal_invalid(),
            "number_a33398bfae5": generate_number_invalid(),
            "datetime_bfae52d8694": generate_datetime_invalid(),
            "richText_76d22d35024": generate_rich_text_invalid(),
            "multilingual_24673c280f2": generate_multilingual_invalid(),
            "date_398bfae52d8": generate_date_invalid(),
            "option_e52d86948bb": generate_option_invalid(),
            "text_7ea7d6a3339": generate_text_invalid(),
            "bigint_7d6a33398bf": generate_bigint_invalid(),
            "boolean_e206a267520": generate_boolean_invalid(),
            "email_f2783b49d9a": generate_email_invalid(),
        }
    }


if __name__ == "__main__":
    import os
    from decimal import Decimal
    
    # 确保data目录存在
    data_dir = os.path.join(os.path.dirname(os.path.dirname(__file__)), "data")
    if not os.path.exists(data_dir):
        os.makedirs(data_dir)
    
    # 生成数据
    data = generate_record()
    
    # 转换浮点数为字符串格式，避免科学计数法
    def convert_floats_to_strings(obj):
        """递归转换浮点数为字符串格式"""
        if isinstance(obj, float):
            # 格式化浮点数，去除不必要的小数点和尾随零
            formatted = f"{obj:.9f}".rstrip('0').rstrip('.')
            return formatted
        elif isinstance(obj, dict):
            return {key: convert_floats_to_strings(value) for key, value in obj.items()}
        elif isinstance(obj, list):
            return [convert_floats_to_strings(item) for item in obj]
        else:
            return obj
    
    # 转换数据中的浮点数
    data_converted = convert_floats_to_strings(data)
    
    # 保存到文件
    output_file = os.path.join(data_dir, "test_manual_cases.json")
    with open(output_file, 'w', encoding='utf-8') as f:
        json.dump(data_converted, f, ensure_ascii=False, indent=2)
    
    print(f"测试数据已生成并保存到: {output_file}")
    print(f"生成的数据内容:")
    print(json.dumps(data_converted, ensure_ascii=False, indent=2))
